package my.jessyan.mvpart.mvp.presenter;

import io.reactivex.schedulers.Schedulers;
import me.jessyan.art.di.component.AppComponent;
import me.jessyan.art.mvp.BasePresenter;
import me.jessyan.art.rxHandler.ErrorHandleSubscriber;
import me.jessyan.art.rxHandler.RetryWithDelay;
import me.jessyan.art.rxHandler.RxErrorHandler;
import me.jessyan.art.utils.HmOSSchedulers;
import my.jessyan.mvpart.mvp.ResourceTable;
import my.jessyan.mvpart.mvp.model.MainRepository;
import my.jessyan.mvpart.mvp.model.User;
import my.jessyan.mvpart.mvp.provider.MainleItemProvider;
import my.jessyan.mvpart.mvp.refresh.PullToRefreshLayout;
import my.jessyan.mvpart.mvp.refresh.TextOverComponent;
import ohos.aafwk.ability.AbilitySlice;
import ohos.agp.components.Component;
import ohos.agp.components.ListContainer;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import org.jetbrains.annotations.NotNull;


import java.util.ArrayList;
import java.util.List;

public class MainPresenter extends BasePresenter<MainRepository> {
    private RxErrorHandler mErrorHandler;
    private AbilitySlice mAbilitySlice;
    private PullToRefreshLayout pullToRefreshLayout;
    private Context mContext;
    private List<User> mUsers = new ArrayList<>();
    private int lastUserId = 1;
    private boolean isFirst = true;
    private int preEndIndex;
    private final int NUM_3=3;
    MainleItemProvider sampleItemProvider;

    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");

    public MainPresenter(AbilitySlice abilitySlice, AppComponent appComponent) {
        super(appComponent.repositoryManager().createRepository(MainRepository.class));
        this.mErrorHandler = appComponent.rxErrorHandler();
        mAbilitySlice = abilitySlice;
        mContext = abilitySlice.getContext();
        initListContainer();
    }

    // 初始化刷新
    public void initRefresh() {
        pullToRefreshLayout = (PullToRefreshLayout) mAbilitySlice.findComponentById(ResourceTable.Id_refresh);
        TextOverComponent textOverComponent = new TextOverComponent(mContext);
        pullToRefreshLayout.setRefreshOverComponent(textOverComponent);
        pullToRefreshLayout.setRefreshListener(new PullToRefreshLayout.RefreshListener() {
            @Override
            public void onRefresh() {
                requestFromModel(true);
                pullToRefreshLayout.refreshFinish();
            }

            @Override
            public void onLoadMore() {
            }
        });
    }

    // 初始化列表
    public void initListContainer() {
        requestFromModel(true);

        ListContainer listContainer = (ListContainer) mAbilitySlice.findComponentById(ResourceTable.Id_list_container);
        sampleItemProvider = new MainleItemProvider(mUsers, mAbilitySlice);
        listContainer.setItemProvider(sampleItemProvider);

        //点击事件
        listContainer.setItemClickedListener(new ListContainer.ItemClickedListener() {
            @Override
            public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
                User item = (User) listContainer.getItemProvider().getItem(i);
                new ToastDialog(mContext)
                        .setText("点击了" + item.getName())
                        .setAlignment(LayoutAlignment.CENTER).show();
            }
        });
    }

    // 网络异常时获取数据用于展示
    private ArrayList<User> getData() {
        ArrayList<User> list = new ArrayList<>();
        list.add(new User("defunkt", "https://avatars.githubusercontent.com/u/2?v=4"));
        list.add(new User("pjhyett", "https://avatars.githubusercontent.com/u/3?v=4"));
        list.add(new User("wycats", "https://avatars.githubusercontent.com/u/4?v=4"));
        list.add(new User("ezmobius", "https://avatars.githubusercontent.com/u/5?v=4"));
        list.add(new User("ivey", "https://avatars.githubusercontent.com/u/6?v=4"));
        list.add(new User("evanphx", "https://avatars.githubusercontent.com/u/7?v=4"));
        list.add(new User("vanpelt", "https://avatars.githubusercontent.com/u/17?v=4"));
        list.add(new User("wayneeseguin", "https://avatars.githubusercontent.com/u/2?v=4"));
        list.add(new User("brynary", "https://avatars.githubusercontent.com/u/19?v=4"));
        list.add(new User("kevinclark", "https://avatars.githubusercontent.com/u/20?v=4"));
        return list;
    }

    // 获取网络数据数据
    private void requestFromModel(boolean pullToRefresh) {
        if (pullToRefresh) lastUserId = 1;//下拉刷新默认只请求第一页
        boolean isEvictCache = true;//是否驱逐缓存,为ture即不使用缓存,每次下拉刷新即需要最新数据,则不使用缓存

        mModel.getUsers(lastUserId, true)
                .subscribeOn(Schedulers.io())
                .retryWhen(new RetryWithDelay(NUM_3, 2))//遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔
                .doOnSubscribe(disposable -> {
                    addDispose(disposable);//在订阅时必须调用这个方法,不然Activity退出时可能内存泄漏
                }).subscribeOn(HmOSSchedulers.mainThread())
                .observeOn(HmOSSchedulers.mainThread())
                .doFinally(() -> {})
                .subscribe(new ErrorHandleSubscriber<List<User>>(mErrorHandler) {
                    @Override
                    public void onNext(@NotNull List<User> list) {
                        lastUserId = list.get(list.size() - 1).getId();//记录最后一个id,用于下一次请求
                        if (pullToRefresh) mUsers.clear();//如果是下拉刷新则清空列表
                        preEndIndex = mUsers.size();//更新之前列表总长度,用于确定加载更多的起始位置
                        mUsers.addAll(list);
                        sampleItemProvider.getData(mUsers);
                        sampleItemProvider.notifyDataChanged();
                    }

                    @Override
                    public void onError(@NotNull Throwable t) {
                        super.onError(t);
                        mUsers = getData();
                        sampleItemProvider.getData(mUsers);
                        sampleItemProvider.notifyDataChanged();
                    }

                });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.mUsers = null;
    }
}
